package main.java.ERMDE.controllers;

import hidden.org.codehaus.plexus.util.DirectoryScanner;

import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.swing.JOptionPane;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import main.java.DMDE.model.Class;
import main.java.DMDE.persistence.conversion.ERMGraphToDMGraphXmlAdapter;
import main.java.DMDE.persistence.conversion.ERMToDMXmlAdapter;
import main.java.DMDE.styling.StyleConstants;
import main.java.ERMDE.application.IShell;
import main.java.ERMDE.controllers.IDiagramController;
import main.java.ERMDE.controllers.IProjectController;
import main.java.ERMDE.controllers.factories.IDiagramControllerFactory;
import main.java.ERMDE.controllers.listeners.IDiagramEventListener;
import main.java.ERMDE.infrastructure.Func;
import main.java.ERMDE.infrastructure.IFileSystemService;
import main.java.ERMDE.infrastructure.IProjectContext;
import main.java.ERMDE.infrastructure.IterableExtensions;
import main.java.ERMDE.infrastructure.visual.DiagramTreeNode;
import main.java.ERMDE.models.Diagram;
import main.java.ERMDE.models.Entity;
import main.java.ERMDE.models.Hierarchy;
import main.java.ERMDE.models.ProjectType;
import main.java.ERMDE.models.Relationship;
import main.java.ERMDE.validation.IProjectValidationService;
import main.java.ERMDE.views.IProjectView;
import main.java.FSMDE.models.Interface;
import main.java.FSMDE.models.Transition;
import main.java.FSMDE.persistence.DiagramXmlManager;
import main.java.common.IXmlFileManager;
import main.java.common.IXmlManager;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class ProjectController implements IProjectController,
	IDiagramEventListener,
	main.java.FSMDE.controllers.listeners.IDiagramEventListener,
	main.java.DMDE.controllers.listeners.IDiagramEventListener {

    public static String DefaultDiagramName = "Principal";

    private IProjectContext ermProjectContext;
    private IDiagramControllerFactory ermDiagramControllerFactory;
    private IDiagramController ermDiagramController;
    private DefaultTreeModel projectTree;
    private IProjectView projectView;
    private IShell shell;
    private DiagramTreeNode ermCurrentDiagramNode;
    private TreeNode editedNode;

    private main.java.FSMDE.infrastructure.IProjectContext fsmProjectContext;
    private main.java.FSMDE.controllers.IDiagramController fsmDiagramController;
    private main.java.FSMDE.controllers.factories.IDiagramControllerFactory fsmDiagramControllerFactory;
    private main.java.FSMDE.infrastructure.visual.DiagramTreeNode fsmCurrentDiagramNode;

    private main.java.DMDE.infrastructure.IProjectContext dmProjectContext;
    private main.java.DMDE.controllers.IDiagramController dmDiagramController;
    private main.java.DMDE.controllers.factories.IDiagramControllerFactory dmDiagramControllerFactory;
    private main.java.DMDE.infrastructure.visual.DiagramTreeNode dmCurrentDiagramNode;

    private IXmlFileManager xmlFileManager;

    private IXmlManager<Diagram> diagramErmXmlManager;
    private main.java.FSMDE.persistence.IXmlManager<main.java.FSMDE.models.Diagram> diagramFsmXmlManager;
    private main.java.DMDE.persistence.DiagramXmlManager diagramDmXmlManager;
    private IFileSystemService fileSystemService;

    private IProjectValidationService ermValidationService;
    private main.java.FSMDE.validation.IProjectValidationService fsmValidationService;
    private ProjectType projectCreatedType;
    private boolean ErmDiagramLoaded;
    private boolean FsmDiagramLoaded;
    private boolean dmDiagramLoaded;

    public ProjectController(
	    main.java.FSMDE.infrastructure.IProjectContext fsmProjectContext,
	    main.java.FSMDE.controllers.factories.IDiagramControllerFactory fsmDiagramControllerFactory,
	    main.java.DMDE.infrastructure.IProjectContext dmProjectContext,
	    main.java.DMDE.controllers.factories.IDiagramControllerFactory dmDiagramControllerFactory,
	    IProjectContext ermProjectContext,
	    IProjectView projectView,
	    IShell shell,
	    IDiagramControllerFactory diagramControllerFactory,
	    IXmlFileManager xmlFileManager,
	    IXmlManager<Diagram> diagramERMXmlManager,
	    main.java.FSMDE.persistence.IXmlManager<main.java.FSMDE.models.Diagram> diagramFSMXmlManager,
	    IFileSystemService fileSystemService,
	    IProjectValidationService validationService,
	    main.java.FSMDE.validation.IProjectValidationService fsmValidationService) {

	this.projectCreatedType = ProjectType.None;
	this.fsmProjectContext = fsmProjectContext;
	this.fsmDiagramControllerFactory = fsmDiagramControllerFactory;
	this.ermProjectContext = ermProjectContext;
	this.ermDiagramControllerFactory = diagramControllerFactory;
	this.dmProjectContext = dmProjectContext;
	this.dmDiagramControllerFactory = dmDiagramControllerFactory;
	this.shell = shell;
	this.projectView = projectView;
	this.projectView.setController(this);
	this.xmlFileManager = xmlFileManager;
	this.diagramErmXmlManager = diagramERMXmlManager;
	this.diagramFsmXmlManager = diagramFSMXmlManager;
	this.fileSystemService = fileSystemService;
	this.ermValidationService = validationService;
	this.fsmValidationService = fsmValidationService;
	this.diagramDmXmlManager = new main.java.DMDE.persistence.DiagramXmlManager();
    }

    public void createProjectFSM(String projectName) {
	this.fsmProjectContext.clearContextDiagrams();
	this.fsmProjectContext.clearProjectDiagrams();
	this.fsmProjectContext.setName(projectName);
	new File(this.fsmProjectContext.getDataDirectory()).mkdirs();

	this.fsmDiagramController = this.fsmDiagramControllerFactory.create();
	this.fsmDiagramController.getDiagram().setName(DefaultDiagramName);
	this.fsmDiagramController.addListener(this);
	this.fsmDiagramController.addErmDiagrams(this.loadAllErmDiagrams());

	main.java.FSMDE.models.Diagram mainDiagram = this.fsmDiagramController
		.getDiagram();

	this.fsmCurrentDiagramNode = new main.java.FSMDE.infrastructure.visual.DiagramTreeNode(
		this.fsmDiagramController.getDiagram(), this.fsmProjectContext);
	this.projectTree = new DefaultTreeModel(this.fsmCurrentDiagramNode);

	this.fsmProjectContext.addContextDiagram(mainDiagram);
	this.fsmProjectContext.addProjectDiagram(mainDiagram);

	this.shell.setRightContent(this.fsmDiagramController.getView());
	this.shell.activateFullSize();

	this.projectCreatedType = ProjectType.Finite_State_Machine;
    }

    private List<main.java.ERMDE.models.Diagram> loadAllErmDiagrams() {

	ArrayList<main.java.ERMDE.models.Diagram> diagrams = new ArrayList<Diagram>();

	for (String projectName : getExistingProjects("erm")) {

	    Document document = null;
	    try {
		document = this.xmlFileManager.read("ejemplos/" + projectName
			+ "/Datos/Principal-comp");
		Element documentElement = document.getDocumentElement();
		Diagram diagram = this.diagramErmXmlManager
			.getItemFromXmlElement(documentElement);
		diagram.setName(projectName);
		diagrams.add(diagram);
	    } catch (Exception e) {
		e.printStackTrace();
	    }

	}

	return diagrams;
    }

    public void createProjectERM(String projectName) {
	this.ermProjectContext.clearContextDiagrams();
	this.ermProjectContext.clearProjectDiagrams();
	this.ermProjectContext.setName(projectName);
	new File(this.ermProjectContext.getDataDirectory()).mkdirs();

	this.ermDiagramController = this.ermDiagramControllerFactory.create();
	this.ermDiagramController.getDiagram().setName(DefaultDiagramName);
	this.ermDiagramController.addListener(this);

	Diagram mainDiagram = this.ermDiagramController.getDiagram();

	this.ermCurrentDiagramNode = new DiagramTreeNode(
		this.ermDiagramController.getDiagram(), this.ermProjectContext);
	this.projectTree = new DefaultTreeModel(this.ermCurrentDiagramNode);

	this.ermProjectContext.addContextDiagram(mainDiagram);
	this.ermProjectContext.addProjectDiagram(mainDiagram);

	this.shell.setRightContent(this.ermDiagramController.getView());
	this.shell.activateFullSize();

	this.projectCreatedType = ProjectType.Entity_Relationship_Model;
    }

    public void createProjectDM(String projectName) {
	this.dmProjectContext.clearContextDiagrams();
	this.dmProjectContext.clearProjectDiagrams();
	this.dmProjectContext.setName(projectName);
	new File(this.dmProjectContext.getDataDirectory()).mkdirs();
	if(this.dmDiagramController != null)
	    this.dmDiagramController.removeListener();
	this.dmDiagramController = this.dmDiagramControllerFactory.create();
	this.dmDiagramController.getDiagram().setName(DefaultDiagramName);
	this.dmDiagramController.addListener(this);

	main.java.DMDE.model.Diagram mainDiagram = this.dmDiagramController
		.getDiagram();

	this.dmCurrentDiagramNode = new main.java.DMDE.infrastructure.visual.DiagramTreeNode(
		this.dmDiagramController.getDiagram(), this.dmProjectContext);
	this.projectTree = new DefaultTreeModel(this.dmCurrentDiagramNode);

	this.dmProjectContext.addContextDiagram(mainDiagram);
	this.dmProjectContext.addProjectDiagram(mainDiagram);

	this.shell.setRightContent(this.dmDiagramController.getView());
	this.shell.activateFullSize();

	this.projectCreatedType = ProjectType.Diagram_Model;
    }

    public IDiagramController getCurrentErmDiagramController() {
	return this.ermDiagramController;
    }

    public main.java.FSMDE.controllers.IDiagramController getCurrentFsmDiagramController() {
	return this.fsmDiagramController;
    }

    public TreeModel getProjectTree() {
	return this.projectTree;
    }

    @Override
    public IProjectView getView() {
	return this.projectView;
    }

    @Override
    public void handleEntityAdded(Diagram diagram, Entity entity) {
	this.ermCurrentDiagramNode.addEntity(entity, this.projectTree);
    }

    @Override
    public void handleRelationshipAdded(Diagram diagram,
	    Relationship relationship) {
	this.ermCurrentDiagramNode.addRelationship(relationship,
		this.projectTree);
    }

    @Override
    public void handleSubDiagramCreated(Diagram diagram, String diagramName) {
	Diagram parentDiagram = this.ermDiagramController.getDiagram();

	IDiagramController childDiagramController = this.ermDiagramControllerFactory
		.create();
	Diagram childDiagram = childDiagramController.getDiagram();

	childDiagram.setName(diagramName);

	parentDiagram.addSubDiagram(childDiagram);
	try {
	    this.ermDiagramController.save();
	} catch (ParserConfigurationException e) {
	    e.printStackTrace();
	}

	DiagramTreeNode childDiagramNode = this.ermCurrentDiagramNode
		.addSubdiagram(childDiagram, this.projectTree);

	this.ermProjectContext.addContextDiagram(childDiagram);
	this.ermProjectContext.addProjectDiagram(childDiagram);

	this.shell.setRightContent(childDiagramController.getView());
	this.ermDiagramController = childDiagramController;

	try {
	    this.ermDiagramController.save();
	} catch (ParserConfigurationException e) {
	    e.printStackTrace();
	}

	this.ermDiagramController.addListener(this);
	this.ermCurrentDiagramNode = childDiagramNode;
    }

    @Override
    public void changeElement(TreePath treePath) {

	switch (projectCreatedType) {
	case Finite_State_Machine: {
	    changeFSMElement(treePath);
	    break;
	}
	case Entity_Relationship_Model: {
	    changeERMElement(treePath);
	    break;
	}
	case Diagram_Model: {
	    changeDMElement(treePath);
	    break;
	}
	default:
	    break;
	}

    }

    private void changeDMElement(TreePath treePath) {
	if (treePath == null)
	    return;
	this.dmProjectContext.clearContextDiagrams();
	main.java.DMDE.model.Diagram diagramToLoad = null;
	for (Object o : treePath.getPath()) {
	    if (o instanceof main.java.DMDE.infrastructure.visual.DiagramTreeNode) {
		main.java.DMDE.infrastructure.visual.DiagramTreeNode node = (main.java.DMDE.infrastructure.visual.DiagramTreeNode) o;
		main.java.DMDE.model.Diagram diagram = (main.java.DMDE.model.Diagram) node.getUserObject();
		diagramToLoad = diagram;
		this.dmCurrentDiagramNode = node;
		this.dmProjectContext.addContextDiagram(diagram);
	    }
	}
	main.java.DMDE.controllers.IDiagramController newController = this.dmDiagramControllerFactory.create();
	try {
	    this.dmDiagramController.save();
	} catch (Exception e) {
	    e.printStackTrace();
	}
	this.dmDiagramController.removeListener();
	if(this.ermDiagramController != null)
	    this.ermDiagramController.removeListener();
	if(this.fsmDiagramController != null)
	    this.fsmDiagramController.removeListener();
	this.dmDiagramController = newController;
	this.dmDiagramController.addListener(this);
	this.dmDiagramController.load(diagramToLoad);
	this.shell.setRightContent(this.dmDiagramController.getView());

	DefaultMutableTreeNode node = (DefaultMutableTreeNode) treePath.getLastPathComponent();
	Object o = node.getUserObject();

	if (o instanceof Class) {
	    this.dmDiagramController.update((main.java.DMDE.model.Class) o);
	    this.editedNode = node;
	} else if (o instanceof main.java.DMDE.model.relationships.Relationship) {
	    this.dmDiagramController.update((main.java.DMDE.model.relationships.Relationship) o);
	    this.editedNode = node;
	} else if (o instanceof main.java.DMDE.model.Interface) {
	    this.dmDiagramController.update((main.java.DMDE.model.Interface) o);
	    this.editedNode = node;
	}
    }

    private void changeFSMElement(TreePath treePath) {
	if (treePath == null)
	    return;

	this.fsmProjectContext.clearContextDiagrams();
	main.java.FSMDE.models.Diagram diagramToLoad = null;
	for (Object o : treePath.getPath()) {
	    if (o instanceof main.java.FSMDE.infrastructure.visual.DiagramTreeNode) {
		main.java.FSMDE.infrastructure.visual.DiagramTreeNode node = (main.java.FSMDE.infrastructure.visual.DiagramTreeNode) o;
		main.java.FSMDE.models.Diagram diagram = (main.java.FSMDE.models.Diagram) node
			.getUserObject();
		diagramToLoad = diagram;
		this.fsmCurrentDiagramNode = node;
		this.fsmProjectContext.addContextDiagram(diagram);
	    }
	}

	main.java.FSMDE.controllers.IDiagramController newController = this.fsmDiagramControllerFactory
		.create();

	try {
	    this.fsmDiagramController.save();
	} catch (ParserConfigurationException e) {
	    e.printStackTrace();
	}

	this.fsmDiagramController = newController;
	this.fsmDiagramController.addErmDiagrams(loadAllErmDiagrams());
	this.fsmDiagramController.addListener(this);
	this.fsmDiagramController.load(diagramToLoad);
	this.shell.setRightContent(this.fsmDiagramController.getView());

	DefaultMutableTreeNode node = (DefaultMutableTreeNode) treePath
		.getLastPathComponent();
	Object o = node.getUserObject();

	if (o instanceof main.java.FSMDE.models.Diagram) {
	    this.fsmDiagramController.refreshComponents();
	    this.projectView.expandPath(treePath);
	}

	if (o instanceof Interface) {
	    this.fsmDiagramController.updateInterface((Interface) o);
	    this.editedNode = node;
	} else if (o instanceof Transition) {
	    this.fsmDiagramController.updateTransition((Transition) o);
	    this.editedNode = node;
	}
    }

    @Override
    public boolean treeNodeIsDiagram(TreePath treePath) {
	DefaultMutableTreeNode node = (DefaultMutableTreeNode) treePath
		.getLastPathComponent();
	Object o = node.getUserObject();

	return o instanceof main.java.FSMDE.models.Diagram;

    }

    private void changeERMElement(TreePath treePath) {
	if (treePath == null)
	    return;
	this.ermProjectContext.clearContextDiagrams();
	Diagram diagramToLoad = null;
	for (Object o : treePath.getPath()) {
	    if (o instanceof DiagramTreeNode) {
		DiagramTreeNode node = (DiagramTreeNode) o;
		Diagram diagram = (Diagram) node.getUserObject();
		diagramToLoad = diagram;
		this.ermCurrentDiagramNode = node;
		this.ermProjectContext.addContextDiagram(diagram);
	    }
	}

	IDiagramController newController = this.ermDiagramControllerFactory
		.create();

	try {
	    this.ermDiagramController.save();
	} catch (ParserConfigurationException e) {
	    e.printStackTrace();
	}

	this.ermDiagramController = newController;
	this.ermDiagramController.addListener(this);
	this.ermDiagramController.load(diagramToLoad);
	this.shell.setRightContent(this.ermDiagramController.getView());

	DefaultMutableTreeNode node = (DefaultMutableTreeNode) treePath
		.getLastPathComponent();
	Object o = node.getUserObject();

	if (o instanceof Entity) {
	    this.ermDiagramController.updateEntity((Entity) o);
	    this.editedNode = node;
	} else if (o instanceof Relationship) {
	    this.ermDiagramController.updateRelationship((Relationship) o);
	    this.editedNode = node;
	} else if (o instanceof Hierarchy) {
	    this.ermDiagramController.updateHierarchy((Hierarchy) o);
	    this.editedNode = node;
	}
    }

    private boolean deleteElementFSM(Object o, DefaultMutableTreeNode node,
	    TreePath treePath) {
	boolean isFSM = false;
	if (o instanceof Interface) {
	    isFSM = true;
	    if (this.fsmDiagramController.deleteInterface((Interface) o)) {
		this.projectTree.removeNodeFromParent(node);

		if (((Interface) o).hasSubDiagram()) {
		    String subdiagramName = ((Interface) o)
			    .getRelatedSubdiagramName();
		    main.java.FSMDE.models.Diagram subdiagram = this.fsmDiagramController
			    .getSubDiagram(subdiagramName);
		    if (subdiagram != null) {
			DefaultMutableTreeNode parentDiagramNode = (DefaultMutableTreeNode) treePath
				.getParentPath().getParentPath()
				.getLastPathComponent();
			Iterable<DefaultMutableTreeNode> descendants = this
				.getDiagramTreeNodeDescendants(parentDiagramNode);

			main.java.FSMDE.infrastructure.visual.DiagramTreeNode nodeToLoad = null;
			for (DefaultMutableTreeNode descendant : descendants) {
			    main.java.FSMDE.infrastructure.visual.DiagramTreeNode nodeAux = (main.java.FSMDE.infrastructure.visual.DiagramTreeNode) descendant;
			    if (((main.java.FSMDE.models.Diagram) nodeAux
				    .getUserObject()).getName().equals(
				    subdiagramName)) {
				nodeToLoad = nodeAux;
				break;
			    }
			}
			this.removeSubdiagram(treePath, nodeToLoad, subdiagram,
				false);
		    }
		}

	    }
	} else if (o instanceof Transition) {
	    isFSM = true;
	    if (this.fsmDiagramController.deleteTransition((Transition) o))
		this.projectTree.removeNodeFromParent(node);
	} else if (o instanceof main.java.FSMDE.models.Diagram) {
	    isFSM = true;
	    if (!((main.java.FSMDE.models.Diagram) o).getName().equals(
		    DefaultDiagramName)) {

		main.java.FSMDE.models.Diagram subdiagramToDelete = ((main.java.FSMDE.models.Diagram) o);

		int result = JOptionPane.showConfirmDialog(null,
			"The Subdiagram " + subdiagramToDelete.getName()
				+ " is being deleted, "
				+ "are you sure you want this?",
			"Deleting Subdiagram " + subdiagramToDelete.getName(),
			JOptionPane.YES_NO_OPTION);

		if (result == JOptionPane.YES_OPTION) {
		    this.removeSubdiagram(treePath, node,
			    (main.java.FSMDE.models.Diagram) o, true);
		}

	    }
	}
	if (isFSM) {
	    try { // saving remove action of any item
		this.fsmDiagramController.save();
	    } catch (ParserConfigurationException e) {
		e.printStackTrace();
	    }
	}
	return isFSM;
    }

    private boolean deleteElementERM(Object o, DefaultMutableTreeNode node) {
	boolean isERM = false;
	if (o instanceof Entity) {
	    isERM = true;
	    if (this.ermDiagramController.deleteEntity((Entity) o))
		this.projectTree.removeNodeFromParent(node);
	} else if (o instanceof Relationship) {
	    isERM = true;
	    if (this.ermDiagramController.deleteRelationship((Relationship) o))
		this.projectTree.removeNodeFromParent(node);
	} else if (o instanceof Hierarchy) {
	    isERM = true;
	    if (this.ermDiagramController.deleteHierarchy((Hierarchy) o))
		this.projectTree.removeNodeFromParent(node);
	}
	return isERM;
    }

    private boolean deleteElementDM(Object o, DefaultMutableTreeNode node) {
	boolean isDM = false;
	if (o instanceof main.java.DMDE.model.Entity) {
	    isDM = true;
	    if (this.dmDiagramController
		    .deleteEntity((main.java.DMDE.model.Entity) o))
		this.projectTree.removeNodeFromParent(node);
	} else if (o instanceof main.java.DMDE.model.relationships.Relationship) {
	    isDM = true;
	    if (this.dmDiagramController
		    .deleteRelationship((main.java.DMDE.model.relationships.Relationship) o))
		this.projectTree.removeNodeFromParent(node);
	}
	return isDM;
    }

    @Override
    public void deleteElement(TreePath treePath) {
	if (treePath == null)
	    return;

	DefaultMutableTreeNode node = (DefaultMutableTreeNode) treePath
		.getLastPathComponent();
	Object o = node.getUserObject();

	if (deleteElementERM(o, node))
	    return;
	if (deleteElementDM(o, node))
	    return;
	deleteElementFSM(o, node, treePath);

    }

    private void removeSubdiagram(TreePath treePath,
	    DefaultMutableTreeNode node,
	    main.java.FSMDE.models.Diagram subdiagramToDelete,
	    boolean unlinkSubdiagramFromInterface) {

	changeElement(treePath.getParentPath().getParentPath());
	DefaultMutableTreeNode parentDiagramNode = (DefaultMutableTreeNode) treePath
		.getParentPath().getParentPath().getLastPathComponent();
	Object parentO = parentDiagramNode.getUserObject();
	try {
	    ((main.java.FSMDE.models.Diagram) parentO)
		    .removeSubDiagram(subdiagramToDelete.getId());
	    if (unlinkSubdiagramFromInterface)
		this.unlinkSubdiagramFromInterface(subdiagramToDelete);
	} catch (Exception e) {
	    e.printStackTrace();
	}
	this.fsmProjectContext.removeDiagram((subdiagramToDelete));
	this.projectTree.removeNodeFromParent(node);
	this.fsmDiagramController.refreshComponents();

	this.deleteSubdiagramFiles(subdiagramToDelete);
    }

    private void deleteSubdiagramFiles(
	    main.java.FSMDE.models.Diagram subdiagramToDelete) {

	for (main.java.FSMDE.models.Diagram subsubdiagram : subdiagramToDelete
		.getSubDiagrams()) {
	    deleteSubdiagramFiles(subsubdiagram);
	}

	// remove subdiagram files
	File diagCompFile = new File(fsmProjectContext.getDataDirectory() + "/"
		+ subdiagramToDelete.getName() + "-comp");
	File diagRepFile = new File(fsmProjectContext.getDataDirectory() + "/"
		+ subdiagramToDelete.getName() + "-rep");

	if (diagCompFile.exists())
	    ;
	diagCompFile.delete();
	if (diagRepFile.exists())
	    ;
	diagRepFile.delete();

    }

    private void unlinkSubdiagramFromInterface(
	    main.java.FSMDE.models.Diagram subdiagramToDelete) {
	for (Interface iface : fsmDiagramController.getAvailableInterfaces()) {
	    if (iface.hasSubDiagram()) {
		if (iface.getRelatedSubdiagramName().equals(
			subdiagramToDelete.getName())) {
		    iface.setSubDiagram("");
		    break;
		}
	    }
	}
    }

    @Override
    public List<String> getExistingProjects(String type) {
	List<String> projects = new ArrayList<String>();
	DirectoryScanner scanner = new DirectoryScanner();
	scanner.setIncludes(new String[] { "**/Principal-comp" });
	scanner.setBasedir(System.getProperty("user.dir"));
	scanner.setCaseSensitive(false);
	scanner.scan();
	String[] files = scanner.getIncludedFiles();

	for (String filePath : files) {
	    File file = new File(filePath);
	    try {
		DocumentBuilderFactory dbFactory = DocumentBuilderFactory
			.newInstance();
		DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
		Document doc;
		doc = dBuilder.parse(file);
		doc.getDocumentElement().normalize();
		if (doc.getDocumentElement().getAttribute("type").toLowerCase()
			.equals(type.toLowerCase())) {
		    projects.add(file.getParentFile().getParentFile().getName());
		}
	    } catch (Exception e) {
		continue;
	    }
	}
	return projects;
    }

    @Override
    public boolean openProject(String projectName) throws Exception {

	this.ermProjectContext.clearContextDiagrams();
	this.ermProjectContext.clearProjectDiagrams();

	this.ermProjectContext.setName(projectName);

	this.fsmProjectContext.clearContextDiagrams();
	this.fsmProjectContext.clearProjectDiagrams();

	this.fsmProjectContext.setName(projectName);

	this.dmProjectContext.clearContextDiagrams();
	this.dmProjectContext.clearProjectDiagrams();

	this.dmProjectContext.setName(projectName);

	if (!this.fileSystemService.exists(
		this.ermProjectContext.getDataDirectory(), DefaultDiagramName)) {

	    return false;
	}
	this.loadDiagram(DefaultDiagramName, null);
	if (this.ErmDiagramLoaded) {
	    this.ermDiagramController = this.ermDiagramControllerFactory
		    .create();
	    this.ermDiagramController.addListener(this);

	    this.ermDiagramController.load(this.ermProjectContext
		    .getContextDiagram(DefaultDiagramName));

	    this.shell.setRightContent(this.ermDiagramController.getView());
	    this.shell.activateFullSize();
	}
	if (this.FsmDiagramLoaded) {
	    this.fsmDiagramController = this.fsmDiagramControllerFactory
		    .create();
	    this.fsmDiagramController.addListener(this);
	    this.fsmDiagramController.addErmDiagrams(this.loadAllErmDiagrams());

	    this.fsmDiagramController.load(this.fsmProjectContext
		    .getContextDiagram(DefaultDiagramName));

	    this.shell.setRightContent(this.fsmDiagramController.getView());
	    this.shell.activateFullSize();
	}
	if (this.dmDiagramLoaded) {
	    if(this.dmDiagramController != null)
		this.dmDiagramController.removeListener();
	    if(this.ermDiagramController != null)
		this.ermDiagramController.removeListener();
	    if(this.fsmDiagramController != null)
		this.fsmDiagramController.removeListener();
	    this.dmDiagramController = this.dmDiagramControllerFactory.create();
	    this.dmDiagramController.addListener(this);
	    this.dmDiagramController.load(this.dmProjectContext
		    .getContextDiagram(DefaultDiagramName));

	    this.shell.setRightContent(this.dmDiagramController.getView());
	    this.shell.activateFullSize();
	}
	return true;
    }

    private void loadDiagram(String diagramName, Object parentTreeNode)
	    throws Exception {

	Document document = this.xmlFileManager.read(this.ermProjectContext
		.getDataDirectory() + "/" + diagramName + "-comp");

	Element documentElement = document.getDocumentElement();
	Diagram diagramErm = this.diagramErmXmlManager
		.getItemFromXmlElement(documentElement);
	if (diagramErm != null) {

	    loadErmDiagram(diagramName, (DiagramTreeNode) parentTreeNode,
		    diagramErm);
	    this.ErmDiagramLoaded = true;
	    this.FsmDiagramLoaded = false;
	    this.dmDiagramLoaded = false;
	    projectCreatedType = ProjectType.Entity_Relationship_Model;
	} else {

	    document = this.xmlFileManager.read(this.fsmProjectContext
		    .getDataDirectory() + "/" + diagramName + "-comp");
	    documentElement = document.getDocumentElement();
	    ((DiagramXmlManager) this.diagramFsmXmlManager)
		    .setErmDiagramas((ArrayList<Diagram>) loadAllErmDiagrams());

	    main.java.FSMDE.models.Diagram diagramFsm = this.diagramFsmXmlManager
		    .getItemFromXmlElement(documentElement);
	    if (diagramFsm != null) {
		loadFsmDiagram(
			diagramName,
			(main.java.FSMDE.infrastructure.visual.DiagramTreeNode) parentTreeNode,
			diagramFsm);
		this.ErmDiagramLoaded = false;
		this.FsmDiagramLoaded = true;
		this.dmDiagramLoaded = false;
		projectCreatedType = ProjectType.Finite_State_Machine;
	    } else {
		document = this.xmlFileManager.read(this.dmProjectContext
			.getDataDirectory() + "/" + diagramName + "-comp");
		documentElement = document.getDocumentElement();
		// ((DiagramXmlManager) this.diagramDmXmlManager)
		// .setErmDiagramas((ArrayList<Diagram>) loadAllErmDiagrams());

		main.java.DMDE.model.Diagram diagramDm = this.diagramDmXmlManager
			.getItemFromXmlElement(documentElement);
		if (diagramDm != null) {
		    loadDmDiagram(
			    diagramName,
			    (main.java.DMDE.infrastructure.visual.DiagramTreeNode) parentTreeNode,
			    diagramDm);
		    this.ErmDiagramLoaded = false;
		    this.FsmDiagramLoaded = false;
		    this.dmDiagramLoaded = true;
		    projectCreatedType = ProjectType.Diagram_Model;
		} else {
		    throw new Exception(
			    "You are trying to open an unrecognized diagram");
		}
	    }
	}
    }

    private void loadDmDiagram(
	    String diagramName,
	    main.java.DMDE.infrastructure.visual.DiagramTreeNode parentTreeNode,
	    main.java.DMDE.model.Diagram diagram) throws Exception {
	diagram.setName(diagramName);
	main.java.DMDE.infrastructure.visual.DiagramTreeNode currentTreeNode;
	if (diagramName.equalsIgnoreCase(DefaultDiagramName)) {
	    this.dmProjectContext.addContextDiagram(diagram);
	    currentTreeNode = new main.java.DMDE.infrastructure.visual.DiagramTreeNode(
		    diagram, this.dmProjectContext);
	    this.dmCurrentDiagramNode = currentTreeNode;
	    this.projectTree = new DefaultTreeModel(this.dmCurrentDiagramNode);
	} else {
	    currentTreeNode = parentTreeNode.addSubdiagram(diagram,   this.projectTree);
	}
	this.dmProjectContext.addProjectDiagram(diagram);
	for (String childDiagramName : diagram.getSubDiagramNames()) {
	    this.loadDiagram(childDiagramName, currentTreeNode);
	}
    }

    @Override
    public ProjectType getProjectType() {
	return this.projectCreatedType;
    }

    private void loadFsmDiagram(
	    String diagramName,
	    main.java.FSMDE.infrastructure.visual.DiagramTreeNode parentTreeNode,
	    main.java.FSMDE.models.Diagram diagram) throws Exception {

	diagram.setName(diagramName);

	main.java.FSMDE.infrastructure.visual.DiagramTreeNode currentTreeNode;

	if (diagramName.equalsIgnoreCase(DefaultDiagramName)) {
	    this.fsmProjectContext.addContextDiagram(diagram);
	    currentTreeNode = new main.java.FSMDE.infrastructure.visual.DiagramTreeNode(
		    diagram, this.fsmProjectContext);
	    this.fsmCurrentDiagramNode = currentTreeNode;
	    this.projectTree = new DefaultTreeModel(this.fsmCurrentDiagramNode);
	} else {
	    currentTreeNode = parentTreeNode.addSubdiagram(diagram,
		    this.projectTree);
	}

	this.fsmProjectContext.addProjectDiagram(diagram);

	for (String childDiagramName : diagram.getSubDiagramNames()) {
	    this.loadDiagram(childDiagramName, currentTreeNode);
	    diagram.addSubDiagram(this.fsmProjectContext
		    .getContextDiagram(childDiagramName));
	}
    }

    private void loadErmDiagram(String diagramName,
	    DiagramTreeNode parentTreeNode, Diagram diagram) throws Exception {

	diagram.setName(diagramName);

	DiagramTreeNode currentTreeNode;

	if (diagramName.equalsIgnoreCase(DefaultDiagramName)) {
	    this.ermProjectContext.addContextDiagram(diagram);
	    currentTreeNode = new DiagramTreeNode(diagram,
		    this.ermProjectContext);
	    this.ermCurrentDiagramNode = currentTreeNode;
	    this.projectTree = new DefaultTreeModel(this.ermCurrentDiagramNode);
	} else {
	    currentTreeNode = parentTreeNode.addSubdiagram(diagram,
		    this.projectTree);
	}

	this.ermProjectContext.addProjectDiagram(diagram);

	for (String childDiagramName : diagram.getSubDiagramNames()) {
	    this.loadDiagram(childDiagramName, currentTreeNode);
	}
    }

    @Override
    public void handleHierarchyAdded(Diagram diagram, Hierarchy hierarchy) {
	this.ermCurrentDiagramNode.addHierarchy(hierarchy, this.projectTree);
    }

    @Override
    public void handleEntityUpdated(Diagram diagram, Entity entity) {
	Func<TreeNode, Boolean, Boolean> cmp = new Func<TreeNode, Boolean, Boolean>() {

	    @Override
	    public Boolean execute(TreeNode node, Boolean notUsed) {
		return node instanceof DiagramTreeNode;
	    }
	};

	Iterable<TreeNode> ancestors = IterableExtensions
		.where(IterableExtensions.getIterableOf(this.projectTree
			.getPathToRoot(this.ermCurrentDiagramNode)), cmp, false);
	Iterable<DefaultMutableTreeNode> descendants = this
		.getDiagramTreeNodeDescendants(this.ermCurrentDiagramNode);

	for (DefaultMutableTreeNode defaultDiagramTreeNode : descendants) {
	    DiagramTreeNode diagramTreeNode = (DiagramTreeNode) defaultDiagramTreeNode;
	    this.updateEntityInDiagram(diagramTreeNode.getDiagram(), entity);
	}

	for (TreeNode treeNode : ancestors) {
	    DiagramTreeNode diagramTreeNode = (DiagramTreeNode) treeNode;
	    this.updateEntityInDiagram(diagramTreeNode.getDiagram(), entity);
	}

	this.projectTree.nodeChanged(this.editedNode);
	this.editedNode = null;
    }

    private void updateEntityInDiagram(Diagram diagram, Entity entity) {
	IDiagramController controller = this.ermDiagramControllerFactory
		.create();
	controller.load(diagram);
	controller.deleteEntityPeripherals(entity);
	controller.handleCreatedEvent(entity);
	try {
	    controller.save();
	} catch (ParserConfigurationException e) {
	    e.printStackTrace();
	}
    }

    private Iterable<DefaultMutableTreeNode> getDiagramTreeNodeDescendants(
	    TreeNode currentNode) {
	List<DefaultMutableTreeNode> diagramTreeNodes = new ArrayList<DefaultMutableTreeNode>();

	int childCount = currentNode.getChildCount();
	for (int i = 0; i < childCount; i++) {
	    TreeNode node = currentNode.getChildAt(i);

	    if (node instanceof DiagramTreeNode)
		diagramTreeNodes.add((DiagramTreeNode) node);
	    else if (node instanceof main.java.FSMDE.infrastructure.visual.DiagramTreeNode)
		diagramTreeNodes
			.add((main.java.FSMDE.infrastructure.visual.DiagramTreeNode) node);

	    for (DefaultMutableTreeNode diagramTreeNode : this
		    .getDiagramTreeNodeDescendants(node)) {
		diagramTreeNodes.add(diagramTreeNode);
	    }
	}

	return diagramTreeNodes;
    }

    @Override
    public void handleRelationshipUpdated(Diagram diagram,
	    Relationship relantionship) {
	this.projectTree.nodeChanged(this.editedNode);
	this.editedNode = null;
    }

    @Override
    public void handleHierarchyUpdated(Diagram diagram, Hierarchy hierarchy) {
	this.projectTree.nodeChanged(this.editedNode);
	this.editedNode = null;
    }

    @Override
    public void validateERMProject(String name, int toleranceLevel) {
	try {
	    openProject(name);
	} catch (Exception e1) {
	    e1.printStackTrace();
	}

	String reportHtml = this.ermValidationService.generateGlobalReport(
		this.ermProjectContext.getName(),
		this.ermProjectContext.getProjectDiagrams(), toleranceLevel);
	SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
	Date date = Calendar.getInstance().getTime();

	String reportName = this.ermProjectContext.getDataDirectory() + "/"
		+ this.ermProjectContext.getName() + "_GeneralProject_"
		+ sdf.format(date) + ".html";

	this.fileSystemService.save(reportName, reportHtml);
	Desktop desktop = Desktop.getDesktop();
	try {
	    desktop.open(new File(reportName));
	} catch (IOException e) {
	    e.printStackTrace();
	}
    }

    @Override
    public void handleInterfaceAdded(main.java.FSMDE.models.Diagram diagram,
	    Interface interface0) {

	this.fsmCurrentDiagramNode.addInterface(interface0, this.projectTree);
    }

    @Override
    public void handleInterfaceUpdated(main.java.FSMDE.models.Diagram diagram,
	    Interface interface0) {

	Func<TreeNode, Boolean, Boolean> cmp = new Func<TreeNode, Boolean, Boolean>() {

	    @Override
	    public Boolean execute(TreeNode node, Boolean notUsed) {
		return node instanceof DiagramTreeNode;
	    }
	};

	Iterable<TreeNode> ancestors = IterableExtensions
		.where(IterableExtensions.getIterableOf(this.projectTree
			.getPathToRoot(this.fsmCurrentDiagramNode)), cmp, false);
	Iterable<DefaultMutableTreeNode> descendants = this
		.getDiagramTreeNodeDescendants(this.fsmCurrentDiagramNode);

	for (DefaultMutableTreeNode defaultDiagramTreeNode : descendants) {
	    main.java.FSMDE.infrastructure.visual.DiagramTreeNode diagramTreeNode = (main.java.FSMDE.infrastructure.visual.DiagramTreeNode) defaultDiagramTreeNode;
	    this.updateInterfaceInDiagram(diagramTreeNode.getDiagram(),
		    interface0);
	}

	for (TreeNode treeNode : ancestors) {
	    main.java.FSMDE.infrastructure.visual.DiagramTreeNode diagramTreeNode = (main.java.FSMDE.infrastructure.visual.DiagramTreeNode) treeNode;
	    this.updateInterfaceInDiagram(diagramTreeNode.getDiagram(),
		    interface0);
	}

	this.projectTree.nodeChanged(this.editedNode);
	// this.projectTree.reload();
	this.editedNode = null;
    }

    private void updateInterfaceInDiagram(
	    main.java.FSMDE.models.Diagram diagram, Interface interface0) {

	main.java.FSMDE.controllers.IDiagramController controller = this.fsmDiagramControllerFactory
		.create();
	controller.load(diagram);
	controller.handleCreatedEvent(interface0);
	try {
	    controller.save();
	} catch (ParserConfigurationException e) {
	    e.printStackTrace();
	}
    }

    @Override
    public void handleTransitionAdded(main.java.FSMDE.models.Diagram diagram,
	    Transition transition) {
	this.fsmCurrentDiagramNode.addTransition(transition, this.projectTree);
    }

    @Override
    public void handleTransitionUpdated(main.java.FSMDE.models.Diagram diagram,
	    Transition transition) {
	Func<TreeNode, Boolean, Boolean> cmp = new Func<TreeNode, Boolean, Boolean>() {

	    @Override
	    public Boolean execute(TreeNode node, Boolean notUsed) {
		return node instanceof DiagramTreeNode;
	    }
	};

	Iterable<TreeNode> ancestors = IterableExtensions
		.where(IterableExtensions.getIterableOf(this.projectTree
			.getPathToRoot(this.fsmCurrentDiagramNode)), cmp, false);
	Iterable<DefaultMutableTreeNode> descendants = this
		.getDiagramTreeNodeDescendants(this.fsmCurrentDiagramNode);

	for (DefaultMutableTreeNode defaultDiagramTreeNode : descendants) {
	    main.java.FSMDE.infrastructure.visual.DiagramTreeNode diagramTreeNode = (main.java.FSMDE.infrastructure.visual.DiagramTreeNode) defaultDiagramTreeNode;
	    this.updateTransitionInDiagram(diagramTreeNode.getDiagram(),
		    transition);
	}

	for (TreeNode treeNode : ancestors) {
	    main.java.FSMDE.infrastructure.visual.DiagramTreeNode diagramTreeNode = (main.java.FSMDE.infrastructure.visual.DiagramTreeNode) treeNode;
	    this.updateTransitionInDiagram(diagramTreeNode.getDiagram(),
		    transition);
	}
    }

    private void updateTransitionInDiagram(
	    main.java.FSMDE.models.Diagram diagram, Transition transition) {
	main.java.FSMDE.controllers.IDiagramController controller = this.fsmDiagramControllerFactory
		.create();
	controller.load(diagram);
	try {
	    controller.handleCreatedEvent(transition);
	    controller.save();
	} catch (ParserConfigurationException e) {
	    e.printStackTrace();
	} catch (Exception e) {
	    e.printStackTrace();
	}

    }

    @Override
    public void handleSubDiagramCreated(main.java.FSMDE.models.Diagram diagram,
	    String diagramName) {

	main.java.FSMDE.models.Diagram parentDiagram = this.fsmDiagramController
		.getDiagram();

	main.java.FSMDE.controllers.IDiagramController childDiagramController = this.fsmDiagramControllerFactory
		.create();
	main.java.FSMDE.models.Diagram childDiagram = childDiagramController
		.getDiagram();

	childDiagram.setName(diagramName);

	parentDiagram.addSubDiagram(childDiagram);
	try {
	    this.fsmDiagramController.save();
	} catch (ParserConfigurationException e) {
	    e.printStackTrace();
	}

	main.java.FSMDE.infrastructure.visual.DiagramTreeNode childDiagramNode = this.fsmCurrentDiagramNode
		.addSubdiagram(childDiagram, this.projectTree);

	this.fsmProjectContext.addContextDiagram(childDiagram);
	this.fsmProjectContext.addProjectDiagram(childDiagram);

	this.shell.setRightContent(childDiagramController.getView());
	this.fsmDiagramController = childDiagramController;

	try {
	    this.fsmDiagramController.save();
	} catch (ParserConfigurationException e) {
	    e.printStackTrace();
	}

	this.fsmDiagramController.addErmDiagrams(this.loadAllErmDiagrams());
	this.fsmDiagramController.addListener(this);
	this.fsmCurrentDiagramNode = childDiagramNode;
    }

    @Override
    public void changeToSubdiagram(String subdiagramName) {

	Iterable<DefaultMutableTreeNode> descendants = this
		.getDiagramTreeNodeDescendants(this.fsmCurrentDiagramNode);

	main.java.FSMDE.infrastructure.visual.DiagramTreeNode nodeToLoad = null;
	main.java.FSMDE.models.Diagram diagramToLoad = null;
	for (DefaultMutableTreeNode descendant : descendants) {
	    main.java.FSMDE.infrastructure.visual.DiagramTreeNode node = (main.java.FSMDE.infrastructure.visual.DiagramTreeNode) descendant;
	    if (((main.java.FSMDE.models.Diagram) node.getUserObject())
		    .getName().equals(subdiagramName)) {
		nodeToLoad = node;
		diagramToLoad = (main.java.FSMDE.models.Diagram) node
			.getUserObject();
		break;
	    }
	}

	if ((diagramToLoad == null) || (nodeToLoad == null))
	    return;

	this.fsmProjectContext.clearContextDiagrams();
	this.fsmCurrentDiagramNode = nodeToLoad;
	this.fsmProjectContext.addContextDiagram(diagramToLoad);
	this.projectView.expandPath(new TreePath(this.fsmCurrentDiagramNode
		.getPath()));

	main.java.FSMDE.controllers.IDiagramController newController = this.fsmDiagramControllerFactory
		.create();
	try {
	    this.fsmDiagramController.save();
	} catch (ParserConfigurationException e) {
	    e.printStackTrace();
	}

	this.fsmDiagramController = newController;
	this.fsmDiagramController.addListener(this);
	this.fsmDiagramController.load(diagramToLoad);
	this.shell.setRightContent(this.fsmDiagramController.getView());
	this.fsmDiagramController.refreshComponents();
    }

    @Override
    public void validateFSMProject(String name) {
	try {
	    openProject(name);
	} catch (Exception e1) {
	    e1.printStackTrace();
	}
	List<main.java.FSMDE.models.Diagram> diagrams = new ArrayList<main.java.FSMDE.models.Diagram>();
	diagrams.add(this.fsmProjectContext.getContextDiagram("Principal"));
	for (main.java.FSMDE.models.Diagram subdiagram : diagrams.get(0)
		.getSubDiagrams()) {
	    diagrams.add(subdiagram);
	}

	String reportHtml = this.fsmValidationService.generateGlobalReport(
		this.fsmProjectContext.getName(), diagrams);
	SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
	Date date = Calendar.getInstance().getTime();
	String reportName = this.fsmProjectContext.getDataDirectory() + "/"
		+ this.fsmProjectContext.getName() + "_FSMProject_"
		+ sdf.format(date) + ".html";
	this.fileSystemService.save(reportName, reportHtml);
	Desktop desktop = Desktop.getDesktop();
	try {
	    desktop.open(new File(reportName));
	} catch (IOException e) {
	    e.printStackTrace();
	}

    }

    public main.java.FSMDE.infrastructure.IProjectContext getFsmContext() {
	return this.fsmProjectContext;
    }

    @Override
    public void updateDiagramName(TreePath editedDiagramPath, String editedName) {

	// change diagram name and save new files..
	main.java.FSMDE.models.Diagram editedDiagram = ((main.java.FSMDE.infrastructure.visual.DiagramTreeNode) (editedDiagramPath
		.getLastPathComponent())).getDiagram();
	String oldEditedName = editedDiagram.getName(); // reserved value for
							// updating interface
							// reference name
	this.changeElement(editedDiagramPath);
	fsmDiagramController.getDiagram().setName(editedName);
	try {
	    fsmDiagramController.save();
	} catch (ParserConfigurationException e) {
	    e.printStackTrace();
	}

	// update interface reference on parent diagram..
	Interface interfaceWithSubdiagram;
	this.changeElement(editedDiagramPath.getParentPath().getParentPath());
	Iterator<Interface> iteInterfaces = fsmDiagramController.getDiagram()
		.getInterfaces().iterator();
	while (iteInterfaces.hasNext()) {
	    interfaceWithSubdiagram = iteInterfaces.next();
	    if (interfaceWithSubdiagram.hasSubDiagram()) {
		if (interfaceWithSubdiagram.getRelatedSubdiagramName().equals(
			oldEditedName)) {
		    interfaceWithSubdiagram.setSubDiagram(editedName);
		    break;
		}
	    }
	}
	// parent diagram reference already updated
	// save Parent Diagram..
	try {
	    fsmDiagramController.save();
	} catch (ParserConfigurationException e) {
	    e.printStackTrace();
	}

	// erase old files..

	File diagCompFile = new File(fsmProjectContext.getDataDirectory() + "/"
		+ oldEditedName + "-comp");
	File diagRepFile = new File(fsmProjectContext.getDataDirectory() + "/"
		+ oldEditedName + "-rep");
	if (diagCompFile.exists())
	    ;
	diagCompFile.delete();
	if (diagRepFile.exists())
	    ;
	diagRepFile.delete();

	// reload edited diagram..
	this.changeElement(editedDiagramPath);

    }

    @Override
    public void handleClassAdded(main.java.DMDE.model.Diagram diagram,
	    Class pendingClass) {
	this.dmCurrentDiagramNode.addEntity(pendingClass, this.projectTree);
    }

    @Override
    public void handleInterfaceUpdated(main.java.DMDE.model.Diagram diagram,
	    main.java.DMDE.model.Interface pendingInterface) {
	// TODO Auto-generated method stub

    }

    @Override
    public void handleRelationshipAdded(main.java.DMDE.model.Diagram diagram,
	    main.java.DMDE.model.relationships.Relationship relationship) {
	this.dmCurrentDiagramNode.addRelationship(relationship,
		this.projectTree);
    }

    @Override
    public void handleInterfaceAdded(main.java.DMDE.model.Diagram diagram,
	    main.java.DMDE.model.Interface pendingInterface) {
	this.dmCurrentDiagramNode.addEntity(pendingInterface, this.projectTree);

    }

    @Override
    public void handleSubDiagramCreated(main.java.DMDE.model.Diagram diagram,
	    String diagramName) {
	main.java.DMDE.model.Diagram parentDiagram = this.dmDiagramController
		.getDiagram();
	main.java.DMDE.controllers.IDiagramController childDiagramController = this.dmDiagramControllerFactory
		.create();
	main.java.DMDE.model.Diagram childDiagram = childDiagramController
		.getDiagram();
	childDiagram.setName(diagramName);
	parentDiagram.addSubDiagram(childDiagram);
	try {
	    this.dmDiagramController.save();
	} catch (Exception e) {
	    e.printStackTrace();
	}
	main.java.DMDE.infrastructure.visual.DiagramTreeNode childDiagramNode = this.dmCurrentDiagramNode
		.addSubdiagram(childDiagram, this.projectTree);

	this.dmProjectContext.addContextDiagram(childDiagram);
	this.dmProjectContext.addProjectDiagram(childDiagram);

	this.shell.setRightContent(childDiagramController.getView());
	this.dmDiagramController = childDiagramController;

	try {
	    this.dmDiagramController.save();
	} catch (Exception e) {
	    e.printStackTrace();
	}
	this.dmDiagramController.addListener(this);
	this.dmCurrentDiagramNode = childDiagramNode;

    }

    @Override
    public void handleClassUpdated(main.java.DMDE.model.Diagram diagram,
	    Class pendingClass) {
	Func<TreeNode, Boolean, Boolean> cmp = new Func<TreeNode, Boolean, Boolean>() {

	    @Override
	    public Boolean execute(TreeNode node, Boolean notUsed) {
		return node instanceof DiagramTreeNode;
	    }
	};

	Iterable<TreeNode> ancestors = IterableExtensions
		.where(IterableExtensions.getIterableOf(this.projectTree
			.getPathToRoot(this.dmCurrentDiagramNode)), cmp, false);
	Iterable<DefaultMutableTreeNode> descendants = this
		.getDiagramTreeNodeDescendants(this.dmCurrentDiagramNode);

	for (DefaultMutableTreeNode defaultDiagramTreeNode : descendants) {
	    main.java.DMDE.infrastructure.visual.DiagramTreeNode diagramTreeNode = (main.java.DMDE.infrastructure.visual.DiagramTreeNode) defaultDiagramTreeNode;
	    this.updateClassInDiagram(diagramTreeNode.getDiagram(), pendingClass);
	}

	for (TreeNode treeNode : ancestors) {
	    main.java.DMDE.infrastructure.visual.DiagramTreeNode diagramTreeNode = (main.java.DMDE.infrastructure.visual.DiagramTreeNode) treeNode;
	    this.updateClassInDiagram(diagramTreeNode.getDiagram(), pendingClass);
	}
	this.projectTree.nodeChanged(this.editedNode);
	this.editedNode = null;
	
    }

    private void updateClassInDiagram(main.java.DMDE.model.Diagram diagram, Class pendingClass) {
	main.java.DMDE.controllers.IDiagramController controller = this.dmDiagramControllerFactory.create();
	controller.load(diagram);
	controller.handleCreatedEvent(pendingClass);
	try {
	    controller.save();
	} catch (ParserConfigurationException e) {
	    e.printStackTrace();
	}
    }

    @Override
    public void convertToDM(String name) {
	String dmProjectName = name + "DM";
	this.dmProjectContext.clearContextDiagrams();
	this.dmProjectContext.clearProjectDiagrams();
	this.dmProjectContext.setName(dmProjectName);
	new File(this.dmProjectContext.getDataDirectory()).mkdirs();
	this.ermProjectContext.setName(name);
	try {
		new main.java.DMDE.persistence.conversion.ERMToDMXmlAdapter().convertXml(this.ermProjectContext.getDataDirectory(), this.dmProjectContext.getDataDirectory(),DefaultDiagramName);
		new main.java.DMDE.persistence.conversion.ERMGraphToDMGraphXmlAdapter().convertXml(this.ermProjectContext.getDataDirectory(), this.dmProjectContext.getDataDirectory(),DefaultDiagramName);
		openProject(name + "DM");
		dmDiagramController.handleCreatedEvent(dmDiagramController.getDiagram().getRelationships());
		dmDiagramController.addAttributeToConvertedGraph();
	} catch (Exception e) {
		e.printStackTrace();
	}
    }

	
	public void convertToFMS(String name) {
		String dmProjectName = name + "DM";
		this.dmProjectContext.clearContextDiagrams();
		this.dmProjectContext.clearProjectDiagrams();
		this.dmProjectContext.setName(dmProjectName);
		new File(this.dmProjectContext.getDataDirectory()).mkdirs();
		this.fsmProjectContext.setName(name);
		try {
			new main.java.DMDE.persistence.conversion.FSMToDMXmlAdapter().convertXml(this.fsmProjectContext.getDataDirectory(), this.dmProjectContext.getDataDirectory(),DefaultDiagramName);
			new main.java.DMDE.persistence.conversion.FSMGraphToDMGraphXmlAdapter().convertXml(this.fsmProjectContext.getDataDirectory(), this.dmProjectContext.getDataDirectory(),DefaultDiagramName);
			openProject(name + "DM");
			dmDiagramController.handleCreatedEvent(dmDiagramController.getDiagram().getRelationships());
			dmDiagramController.addAttributeToConvertedGraph();
		} catch (Exception e) {
			e.printStackTrace();
		}	
	}

}
